package demo04;

/*
 * 局部内部类如果希望访问所在方法的局部变量，那么这个局部变量必须是【有效final的】。
 * 
 * 备注：从Java 8+开始，只要局部变量事实没有被改变过，那么final关键字可以省略。（Java 8以前不能省略！）
 * 
 * 原因：
 * 1. new出来的对象在堆内存当中
 * 2. 局部变量是跟着方法走的，在栈内存当中
 * 3. 方法运行结束之后，会立刻出栈，局部变量立刻消失
 * 4. 但是new出来的对象会在堆中持续存在，直到垃圾回收消失
 * 5. 局部变量会在方法结束后马上消失，所以该变量得是个不会改变的常值，得以提前拷贝一份该值放入到类中使用，才能让内部类使用时能正常访问到所在方法的局部变量（常量）
 */
public class MyOuter {
    public void methodOuter() {
        int num = 10; // 所在方法的局部变量存储在栈中，方法结束会立刻消失
        // num = 20; // 错误写法！如果想要局部内部类使用其所在方法的局部变量，那么该变量必须有常属性，不能被改变

        class MyInner { // 为了能在局部内部类中使用类外方法的局部变量，该局部变量必须是常值，不可改变
            public void methodInner() {
                System.out.println(num); // 类中记录了num的常值10，以保证即使类外的方法出栈消失了，在堆中还能留有num的值信息，以防止找不到num的值而出错
            }
        }
        new MyInner().methodInner(); // new出来的新对象存储在堆中，程序结束垃圾回收时才会消失
    }
}
